/**
 * IndexedDB 存储封装类
 * 提供与 localStorage 相似的 API 接口，但支持更大的存储容量
 * 使用异步操作，避免阻塞主线程
 */
class IndexedDBStorage {
    constructor() {
        // 数据库配置常量
        this.DB_NAME = 'TodoListDB';
        this.DB_VERSION = 1;
        this.STORE_NAME = 'todoData';
        
        // 数据库实例
        this.db = null;
        
        // 初始化数据库
        this.initDB();
    }

    /**
     * 初始化 IndexedDB 数据库
     * @returns {Promise<void>}
     */
    async initDB() {
        return new Promise((resolve, reject) => {
            // 检查浏览器是否支持 IndexedDB
            if (!window.indexedDB) {
                console.error('当前浏览器不支持 IndexedDB');
                reject(new Error('IndexedDB not supported'));
                return;
            }

            // 打开数据库连接
            const request = indexedDB.open(this.DB_NAME, this.DB_VERSION);

            // 数据库升级事件（首次创建或版本更新时触发）
            request.onupgradeneeded = (event) => {
                this.db = event.target.result;
                
                // 创建对象存储空间（相当于表）
                if (!this.db.objectStoreNames.contains(this.STORE_NAME)) {
                    const objectStore = this.db.createObjectStore(this.STORE_NAME, {
                        keyPath: 'key'
                    });
                    
                    // 创建索引以提高查询性能
                    objectStore.createIndex('key', 'key', { unique: true });
                }
            };

            // 数据库打开成功
            request.onsuccess = (event) => {
                this.db = event.target.result;
                console.log('IndexedDB 数据库初始化成功');
                resolve();
            };

            // 数据库打开失败
            request.onerror = (event) => {
                console.error('IndexedDB 数据库初始化失败:', event.target.error);
                reject(event.target.error);
            };
        });
    }

    /**
     * 设置数据项
     * @param {string} key - 存储键
     * @param {any} value - 存储值
     * @returns {Promise<void>}
     */
    async setItem(key, value) {
        return new Promise((resolve, reject) => {
            if (!this.db) {
                reject(new Error('数据库未初始化'));
                return;
            }

            // 创建事务
            const transaction = this.db.transaction([this.STORE_NAME], 'readwrite');
            const objectStore = transaction.objectStore(this.STORE_NAME);

            // 准备存储的数据对象
            const dataItem = {
                key: key,
                value: value,
                timestamp: Date.now()
            };

            // 执行存储操作
            const request = objectStore.put(dataItem);

            request.onsuccess = () => {
                resolve();
            };

            request.onerror = (event) => {
                console.error('数据存储失败:', event.target.error);
                reject(event.target.error);
            };

            transaction.onerror = (event) => {
                console.error('事务执行失败:', event.target.error);
                reject(event.target.error);
            };
        });
    }

    /**
     * 获取数据项
     * @param {string} key - 存储键
     * @returns {Promise<any>} 存储的值，如果不存在则返回 null
     */
    async getItem(key) {
        return new Promise((resolve, reject) => {
            if (!this.db) {
                reject(new Error('数据库未初始化'));
                return;
            }

            // 创建只读事务
            const transaction = this.db.transaction([this.STORE_NAME], 'readonly');
            const objectStore = transaction.objectStore(this.STORE_NAME);

            // 执行查询操作
            const request = objectStore.get(key);

            request.onsuccess = (event) => {
                const result = event.target.result;
                resolve(result ? result.value : null);
            };

            request.onerror = (event) => {
                console.error('数据读取失败:', event.target.error);
                reject(event.target.error);
            };
        });
    }

    /**
     * 删除数据项
     * @param {string} key - 存储键
     * @returns {Promise<void>}
     */
    async removeItem(key) {
        return new Promise((resolve, reject) => {
            if (!this.db) {
                reject(new Error('数据库未初始化'));
                return;
            }

            // 创建读写事务
            const transaction = this.db.transaction([this.STORE_NAME], 'readwrite');
            const objectStore = transaction.objectStore(this.STORE_NAME);

            // 执行删除操作
            const request = objectStore.delete(key);

            request.onsuccess = () => {
                resolve();
            };

            request.onerror = (event) => {
                console.error('数据删除失败:', event.target.error);
                reject(event.target.error);
            };
        });
    }

    /**
     * 清空所有数据
     * @returns {Promise<void>}
     */
    async clear() {
        return new Promise((resolve, reject) => {
            if (!this.db) {
                reject(new Error('数据库未初始化'));
                return;
            }

            // 创建读写事务
            const transaction = this.db.transaction([this.STORE_NAME], 'readwrite');
            const objectStore = transaction.objectStore(this.STORE_NAME);

            // 执行清空操作
            const request = objectStore.clear();

            request.onsuccess = () => {
                resolve();
            };

            request.onerror = (event) => {
                console.error('数据清空失败:', event.target.error);
                reject(event.target.error);
            };
        });
    }

    /**
     * 获取所有存储键
     * @returns {Promise<string[]>}
     */
    async getAllKeys() {
        return new Promise((resolve, reject) => {
            if (!this.db) {
                reject(new Error('数据库未初始化'));
                return;
            }

            // 创建只读事务
            const transaction = this.db.transaction([this.STORE_NAME], 'readonly');
            const objectStore = transaction.objectStore(this.STORE_NAME);

            // 执行获取所有键的操作
            const request = objectStore.getAllKeys();

            request.onsuccess = (event) => {
                resolve(event.target.result);
            };

            request.onerror = (event) => {
                console.error('获取键列表失败:', event.target.error);
                reject(event.target.error);
            };
        });
    }

    /**
     * 获取存储的数据项数量
     * @returns {Promise<number>}
     */
    async length() {
        return new Promise((resolve, reject) => {
            if (!this.db) {
                reject(new Error('数据库未初始化'));
                return;
            }

            // 创建只读事务
            const transaction = this.db.transaction([this.STORE_NAME], 'readonly');
            const objectStore = transaction.objectStore(this.STORE_NAME);

            // 执行计数操作
            const request = objectStore.count();

            request.onsuccess = (event) => {
                resolve(event.target.result);
            };

            request.onerror = (event) => {
                console.error('获取数据项数量失败:', event.target.error);
                reject(event.target.error);
            };
        });
    }

    /**
     * 检查数据库是否已初始化
     * @returns {boolean}
     */
    isReady() {
        return this.db !== null;
    }

    /**
     * 等待数据库准备就绪
     * @param {number} timeout - 超时时间（毫秒）
     * @returns {Promise<void>}
     */
    async waitForReady(timeout = 10000) {
        // 如果已经准备就绪，直接返回
        if (this.isReady()) {
            return;
        }
        
        const startTime = Date.now();
        
        return new Promise((resolve, reject) => {
            const checkReady = () => {
                if (this.isReady()) {
                    resolve();
                    return;
                }
                
                if (Date.now() - startTime > timeout) {
                    reject(new Error('数据库初始化超时'));
                    return;
                }
                
                // 等待 100ms 后重新检查
                setTimeout(checkReady, 100);
            };
            
            checkReady();
        });
    }

    /**
     * 关闭数据库连接
     */
    close() {
        if (this.db) {
            this.db.close();
            this.db = null;
            console.log('IndexedDB 数据库连接已关闭');
        }
    }
}

// 导出类供其他模块使用
window.IndexedDBStorage = IndexedDBStorage;